﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Xml.Serialization;

namespace SearchScreen.SDK
{
    public class CriteriaLabelSelector : DataTemplateSelector
    {
        public string DisplayMemberPath { get; set; }

        public Binding ItemClickedCommand { get; set; }

        private Dictionary<Type, DataTemplate> dataTemplateCache = new Dictionary<Type,DataTemplate>();

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            Type type;

            if (!String.IsNullOrWhiteSpace(this.DisplayMemberPath))
            {
                type = item.GetType().GetProperty(this.DisplayMemberPath).GetValue(item, null).GetType();
            }
            else
            {
                type = item.GetType();
            }
            
            DataTemplate template;

            if (!this.dataTemplateCache.TryGetValue(type, out template))
            {
                template = new DataTemplate(type);
                var factory = template.VisualTree = new FrameworkElementFactory(typeof(StackPanel));
                factory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
                factory.SetValue(StackPanel.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);

                foreach (var p in type.GetProperties(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Public))
                {
                    var customAttributes = p.GetCustomAttributes(true);

                    var consideredAttribute = customAttributes.OfType<SearchCriteriaAttribute>().FirstOrDefault();

                    if (null != consideredAttribute)
                    {
                        var labelFactory = new FrameworkElementFactory(typeof(TextBlock));
                        labelFactory.SetValue(TextBlock.TextProperty, consideredAttribute.Id);

                        factory.AppendChild(labelFactory);
                    }
                }
                var button = new FrameworkElementFactory(typeof(Button));
                var buttonText = new FrameworkElementFactory(typeof(TextBlock));
                buttonText.Text = "...";
                button.AppendChild(buttonText);

                button.SetBinding(Button.CommandProperty, this.ItemClickedCommand);
                button.SetBinding(Button.CommandParameterProperty,
                    new Binding());

                factory.AppendChild(button);
            }

            return template;
        }

    }

}
